package com.free.semantic.core.concept.impl;

import com.free.semantic.common.Ls;
import com.free.semantic.core.ConceptInstanceManage;
import com.free.semantic.core.ConceptManage;
import com.free.semantic.core.concept.BaseConcept;
import com.free.semantic.core.proxy.ProxyFunctionProvider;
import com.free.semantic.core.proxy.impl.ConceptInsManageProxy;
import com.free.semantic.core.takeclient.impl.UrlClientImpl;
import com.free.semantic.utils.Utils;

import java.util.List;
import java.util.Set;

import static com.free.semantic.core.concept.impl.ConceptSelfInfoConcept.*;
import static com.free.semantic.utils.Utils.*;

public class ImplementRegisterConcept implements BaseConcept {

    /**
     * 关系定义
     */
    public static final String FIND_ONE_BY_3 = "findOneBy3";

    public static final Set<String> relationLs = Ls.ofSet(FIND_ONE_BY_3);

    /**
     * 概念定义
     */
    public static final String FUNCTION_PROVIDER = "functionProvider";

    public static final String FUNCTION_PROVIDER_NAME = "functionProviderName";

    public static final String SEMANTIC_IMPLEMENT = "semanticImplement";

    public static final String SEMANTIC_IMPLEMENT_URL = "semanticImplementUrl";

    /**
     * 动作定义
     */
    public static final String CREATE_FUNCTION_PROVIDER = "createFunctionProvider";

    public static final Set<String> conceptLs = Ls.ofSet(SEMANTIC_IMPLEMENT,
            FUNCTION_PROVIDER, SEMANTIC_IMPLEMENT_URL, FUNCTION_PROVIDER_NAME, CREATE_FUNCTION_PROVIDER);

    @Override
    public void initRelationDef(ConceptManage conceptManage) {
        Utils.addRelationDef(conceptManage, FIND_ONE_BY_3, defineItem(oneObj("A", "B", "C"), oneObj("D")));
        Utils.createRelation(conceptManage, FIND_MORE, SEMANTIC_IMPLEMENT, FUNCTION_PROVIDER);
        Utils.createRelation2(conceptManage, FIND_ONE_BY_3, SEMANTIC_IMPLEMENT, FUNCTION_PROVIDER_NAME,
                SEMANTIC_IMPLEMENT_URL, CREATE_FUNCTION_PROVIDER);

        Utils.createRelation2(conceptManage, FIND_ONE_BY_ONE_ONE, SEMANTIC_IMPLEMENT, SEMANTIC_IMPLEMENT_URL, CONCEPT_INS_TAKE_COMMAND);

        Utils.createRelation(conceptManage, FIND_ONE, SEMANTIC_IMPLEMENT, SEMANTIC_NET);

    }

    @Override
    public void initConcept(ConceptManage conceptManage) {
        for (String keyConceptL : conceptLs) {
            conceptManage.addConcept(keyConceptL);
        }
    }

    @Override
    public void initConceptImpl(ConceptInstanceManage instanceManage) {

        instanceManage.registerFunction(Ls.of(SEMANTIC_IMPLEMENT), FUNCTION_PROVIDER, context -> {
            List<String> providerLs = instanceManage.getProviderLs();
            context.setValue(FUNCTION_PROVIDER, providerLs);
        });

        instanceManage.registerFunction(Ls.of
                        (SEMANTIC_IMPLEMENT, FUNCTION_PROVIDER_NAME, SEMANTIC_IMPLEMENT_URL),
                CREATE_FUNCTION_PROVIDER, context -> {
                    List<String> urlLs = context.getListValue(SEMANTIC_IMPLEMENT_URL);
                    String url = urlLs.get(0);

                    List<String> providerNameLs = context.getListValue(FUNCTION_PROVIDER_NAME);
                    String providerName = providerNameLs.get(0);
                    UrlClientImpl client = new UrlClientImpl(url);

                    ConceptInsManageProxy proxy = new ConceptInsManageProxy(client);

                    ProxyFunctionProvider provider = new ProxyFunctionProvider(proxy.concept(), proxy);
                    provider.prepareFunctionMap();
                    instanceManage.registerFunction(providerName, provider);

                    context.setValue(FUNCTION_PROVIDER, true);
                });

        instanceManage.registerFunction(Ls.of
                        (SEMANTIC_IMPLEMENT, SEMANTIC_IMPLEMENT_URL),
                CONCEPT_INS_TAKE_COMMAND, context -> {
                    List<String> urlLs = context.getListValue(SEMANTIC_IMPLEMENT_URL);
                    String url = urlLs.get(0);
                    UrlClientImpl client = new UrlClientImpl(url);
                    context.setValue(CONCEPT_INS_TAKE_COMMAND, client);
                });
        registerTheSameFunction(instanceManage, SEMANTIC_IMPLEMENT, SEMANTIC_NET);
    }


}


